package com.warom.sdg.modbus;

import android.util.Log;

import com.warom.sdg.callback.PlcDataListener;
import com.warom.sdg.config.MeasurementPoint;
import com.warom.sdg.config.PlcMeasurementUtils;
import com.warom.sdg.model.PlcDataEntity;
import com.warom.sdg.model.PlcDeviceEntity;
import com.warom.sdg.service.PlcDataService;
import com.warom.sdg.util.LogUtils;

/**
 * 设备数据监听器 - 处理设备数据回调
 */
public class DeviceDataListener implements PlcDataListener {
    private static final String TAG = "DeviceDataListener";
    
    private PlcDeviceEntity device;
    private PlcDataService dataService;

    public DeviceDataListener(PlcDeviceEntity device, PlcDataService dataService) {
        this.device = device;
        this.dataService = dataService;
    }

    @Override
    public void onDataReceived(Object data, String dataType, String address) {
        // 处理接收到的数据
        Log.d(TAG, "设备[" + device.getDeviceName() + "]接收到数据: " +
                (data != null ? data.toString() : "null") + ", 类型: " + dataType +
                ", 地址: " + address);

        if (address.equals("40057")) {
            Log.i("aa", "bbb");
        }
        
        // 保存数据
        handleReceivedData(device, data, dataType, address);

        // 更新设备状态为活跃
        dataService.updateDeviceStatus(device, true);
    }

    @Override
    public void onError(String error) {
        Log.e(TAG, "设备[" + device.getDeviceName() + "]通信错误: " + error);

        // 更新设备状态为不活跃
        dataService.updateDeviceStatus(device, false);
    }
    
    /**
     * 处理接收到的数据
     * 
     * @param device   设备实体
     * @param data     数据对象
     * @param dataType 数据类型
     */
    private void handleReceivedData(PlcDeviceEntity device, Object data, String dataType, String address) {
        if (data == null) {
            return;
        }
        LogUtils.logOperation(TAG, "handleReceivedData", device.toString());
        try {
            // 处理保持寄存器数据
            if (data instanceof int[] && dataType != null) {
                int[] values = (int[]) data;
                if (values.length > 0) {
                    // 从实际地址查找测点配置信息
                    MeasurementPoint measurementPoint = findMeasurementConfig(device, address);

                    if (measurementPoint != null) {
                        // 处理原始值
                        float scaledValue = processValue(values[0], measurementPoint);

                        // 更新内存中的实时值
                        measurementPoint.setValue(scaledValue);
                        
                        // 更新测点的最后读取时间
                        measurementPoint.updateLastUpdateTime();
                        
                        if ("Circulation_Fan_1".equals(measurementPoint.getEnglishName())) {
                            Log.i("AA", "BB");
                        }
                        
                        // 仅对数值型测点进行数据库保存
                        if (measurementPoint.getPointType() == MeasurementPoint.PointType.VALUE) {
                            // 保存数据到数据库，使用格式化的字符串确保只有2位小数
//                            dataService.saveData(device.getDeviceId(), measurementPoint.getName(), address, "",
//                                    String.format("%.2f", scaledValue), measurementPoint.getUnit());
                        } else {
                            LogUtils.logDebug(TAG, "状态型测点，不保存到数据库: " + measurementPoint.getName());
                        }
                    } else {
                        LogUtils.logError(TAG, "未找到测点配置: " + address);
                    }
                }
            }
            // 处理位数据 (线圈/离散输入)
            else if (data instanceof boolean[]) {
                boolean[] bits = (boolean[]) data;
                // 从实际地址查找测点配置信息
                MeasurementPoint measurementPoint = findMeasurementConfig(device, address);
                if (measurementPoint != null) {
                    LogUtils.logDebug(TAG,
                            "测点: " + measurementPoint.getName() + ", 地址: " + address + ", 类型: "
                                    + measurementPoint.getPointType() +
                                    ", 子类型: " + measurementPoint.getDeviceSubType() + ", 原始值: " + bits[0]);
                    // 更新内存中的实时值,将true or false 转成0和1
                    float value = bits[0] ? 1 : 0;
                    measurementPoint.setValue(value);
                    
                    // 更新测点的最后读取时间
                    measurementPoint.updateLastUpdateTime();
                } else {
                    LogUtils.logError(TAG, "未找到测点配置: " + address);
                }
            }
        } catch (Exception e) {
            LogUtils.logError(TAG, "处理接收数据异常: " + e.getMessage());
        }
    }

    /**
     * 查找测点配置信息
     * 根据设备ID和地址查找对应的测点配置
     */
    private MeasurementPoint findMeasurementConfig(PlcDeviceEntity device, String address) {
        if (device == null) {
            Log.w(TAG, "设备为空，无法查找测点配置");
            return null;
        }

        // 获取设备类型ID
        int deviceTypeId = device.getDeviceTypeId();
        if (deviceTypeId <= 0) {
            deviceTypeId = 1; // 默认使用西门子S7的ID
            Log.w(TAG, "设备 " + device.getDeviceName() + " 无有效的设备类型ID，使用默认ID: " + deviceTypeId);
        }

        // 使用PlcMeasurementConfig的辅助方法查找测点配置
        PlcDataEntity entity = PlcMeasurementUtils.findMeasurementEntity(
                device.getDeviceId(), deviceTypeId, address);

        if (entity != null) {
            // 获取对应的测点配置
            MeasurementPoint point = PlcMeasurementUtils.findMeasurementPoint(deviceTypeId,
                    address);

            Log.d(TAG, "找到地址 " + address + " 的测点配置: " +
                    entity.getName() + ", 缩放因子: " + point.getScaleFactor());
            return point;
        }

        // 未找到匹配的测点
        Log.w(TAG, "未找到地址 " + address + " 的测点配置");
        return null;
    }

    /**
     * 处理数值转换
     * 根据测点配置对原始值进行处理
     */
    private float processValue(float rawValue, MeasurementPoint config) {
        try {
            // 针对异常数据做特殊处理
            if (rawValue > 60000) {
                return 0f;
            }
            // 获取缩放因子
            float scaleFactor = config.getScaleFactor();
            if (scaleFactor != 0) {
                // 应用缩放因子（除以因子获得实际值）
                float result = rawValue / scaleFactor;
                // 格式化为保留2位小数
                result = Math.round(result * 100) / 100.0f;
                Log.d(TAG, "应用缩放因子: " + rawValue + " / " + scaleFactor + " = " + result);
                if (config.getAddress().equals("42062")) {
                    LogUtils.logOperation("test", "test", "test");
                }
                return result;
            }
            // 即使没有缩放因子，也保留2位小数
            return Math.round(rawValue * 100) / 100.0f;

        } catch (Exception e) {
            Log.e(TAG, "处理数值转换失败", e);
            // 转换失败时返回原始值，但仍保留2位小数
            return Math.round(rawValue * 100) / 100.0f;
        }
    }
}
